﻿using BudgetManager.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BudgetManager.Data
{
    /// <summary>
    /// Class for all Dataa access activities
    /// </summary>
    public class BudgetMgrDAL
    {
        BudgetMgrDataContext dataContext = new BudgetMgrDataContext("Data Source=isostore:/ExpenseDB2.sdf");
        /// <summary>
        /// Insert a Category record
        /// </summary>
        /// <param name="category">record to be inserted</param>
        public void SaveCategory(Category category)
        {
            dataContext.Categories.InsertOnSubmit(category);
            dataContext.SubmitChanges();
        }

        /// <summary>
        /// Gets the list of categories available
        /// </summary>
        /// <returns>List of all categories available in database</returns>
        public List<Category> LoadCategories()
        {
            List<Category> categories = new List<Category>();
            return dataContext.Categories.Select(cat => cat).ToList();
        }

        /// <summary>
        /// Inserts an expense record
        /// </summary>
        /// <param name="expense">expense details to be saved</param>
        public void AddExpense(Expense expense)
        {
            dataContext.Expenses.InsertOnSubmit(expense);
            dataContext.SubmitChanges();
        }

        /// <summary>
        /// Updates an expense record
        /// </summary>
        /// <param name="expense">expense details to be saved</param>
        public void UpdateExpense(Expense expense)
        {
            var exp = dataContext.Expenses.First(e => e.ExpenseId == expense.ExpenseId);
            if (exp != null)
            {
                exp.ExpenseAmount = expense.ExpenseAmount;
                exp.Category = expense.Category;
                exp.Comments = expense.Comments;
                exp.ExpenseDate = expense.ExpenseDate;
                //var chngSet = dataContext.GetChangeSet();
                dataContext.SubmitChanges();
            }
        }

        /// <summary>
        /// Deletes a category along with all expense record related to it
        /// </summary>
        /// <param name="catName">Category to be deleted</param>
        private void DeleteCategory(string catName)
        {
            //Delete all expense records related to the category, then delete the category

            var expenses = dataContext.Expenses.Where(e => e.Category == catName);
            dataContext.Expenses.DeleteAllOnSubmit(expenses);
            dataContext.SubmitChanges();

            //Delete Category
            var category = dataContext.Categories.First(c => c.Name == catName);
            if (category != null)
            {
                dataContext.Categories.DeleteOnSubmit(category);
                dataContext.SubmitChanges();
            }
        }

        /// <summary>
        /// Gets all expenses based on categories
        /// </summary>
        /// <param name="categories">categories for which expense records are required</param>
        /// <returns>Expense records</returns>
        public List<Expense> LoadExpenses(List<string> categories)
        {
            List<Expense> expenses = new List<Expense>();
            if (categories != null && categories.Count > 0)
            {
            }
            else
            {
                expenses = dataContext.Expenses.Select(a => a).ToList();
            }
            return expenses;
        }

        public float GetTotalExpense(DateTime startdate, DateTime endDate)
        {
            float total = 0;
            var expenses = dataContext.Expenses;
            if (expenses != null && expenses.Count() > 0)
            {
                var v = expenses.Where(exp => exp.ExpenseDate >= startdate && exp.ExpenseDate <= endDate).Select(e => e).ToList();
                total = v.Count > 0 ? v.Sum(ex => ex.ExpenseAmount) : 0;
            }
            return total;
        }

        public float GetTotalExpense()
        {
            float total = 0;
            var expenses = dataContext.Expenses;
            if (expenses != null && expenses.Count() > 0)
            {
                total = expenses.Sum(ex => ex.ExpenseAmount);
            }
            return total;
        }

        public List<Expense> GetDetailedExpenses(DateTime? startDate = null, DateTime? endDate = null)
        {
            List<Expense> expenses = new List<Expense>();
            var allexp = dataContext.Expenses.ToList();
            if (allexp != null && allexp.Count() > 0 && startDate != null && endDate != null)
            {
                expenses = allexp.Where(ex => ex.ExpenseDate >= startDate && ex.ExpenseDate <= endDate).Select(a => a).ToList();
            }
            else
            {
                expenses = allexp;
            }
            return expenses;
        }

        public void DeleteCategory(System.Collections.IList selectedItems)
        {
            foreach (var item in selectedItems)
            {
                DeleteCategory(item.ToString());
            }
        }

        public bool DeleteExpense(int expenseId)
        {
            bool status = false;
            var expense = dataContext.Expenses.FirstOrDefault(e => e.ExpenseId == expenseId);
            if (expense != null)
            {
                dataContext.Expenses.DeleteOnSubmit(expense);
                dataContext.SubmitChanges();
                status = true;
            }
            return status;
        }
    }
}
